home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr47
/
wasm223.zip
/
TRANSFER.ASM
< prev
next >
Wrap
Assembly Source File
|
1993-05-04
|
16KB
|
588 lines
;************************;
; SESSION File Transfers ;
; By Eric Tauck ;
;************************;
MAXLINE EQU 512 ;maximum line length
INPBUF EQU 4096 ;read input buffer size
t_han DW 0FFFFH ;text write handle
t_fil DW 0FFFFH ;text read file block address
t_rea DB 'Text file to send: ',0
t_wri DB 'Text file to receive: ',0
x_upl DB 'Xmodem file to send: ',0
x_dwn DB 'Xmodem file to receive: ',0
x_conf DB 'File already exists, overwrite',0
t_err DB 'Could not open file',0
t_err1 DB 'Error opening or reading from file',0
t_err2 DB 'Error opening or writing to file',0
x_err DB 'Unable to complete transfer',0
x_uplp DB 'Xmodem Upload ', 249, ' ', 0
x_dwnp DB 'Xmodem Download ', 249, ' ', 0
x_crc DB 'CRC',0
x_sum DB 'SUM',0
x_bytes DB ' ', 249, ' Bytes=',0
x_error DB ' ', 249, ' Errors=',0
x_last DB ' ', 249, ' Last=',0
;========================================
; Begin reading text.
;
; In: AX= name of file (or 0 if none).
;
; Out: CY= set if error.
Text_Read_Beg PROC NEAR
push di
push si
StkAll di, 80 ;allocate space for file name
cmp t_fil, 0FFFFH ;check if already reading
je texbeg1
push ax
call Text_Read_End ;finish reading first
pop ax
;--- input file name
texbeg1 or ax, ax ;check if passed
jz texbeg2 ;jump if not
mov bx, di
call StrCpy ;copy to buffer
jmps texbeg3
texbeg2 mov ax,OFFSET t_rea ;prompt
mov bx, di ;storage for file name
call Command_Input ;input a file name
jc texbeg6 ;jump if cancel
;--- open file
texbeg3 mov si,OFFSET t_rec ;uninitialized read record
mov ax, INPBUF ;buffer size
mov bx, si
call BufAll ;allocate buffer
jc texbeg5
mov ax, di ;address of name
mov bx, si
mov cl, BUFFER_READ ;access
call BufOpn ;try to open
jc texbeg4
mov t_fil, si ;record address
StkRel 80 ;fix stack
pop si
pop di
clc
ret
;--- error
texbeg4 mov bx, si
call BufRel ;release buffer
texbeg5 mov ax, OFFSET t_err ;error message
call Command_Error ;display
;--- finished
texbeg6 StkRel 80 ;fix stack
pop si
pop di
stc
ret
ENDP
;========================================
; Finish reading text.
Text_Read_End PROC NEAR
cmp t_fil, 0FFFFH ;check if not open
je texren1 ;jump if so
push di
mov di, t_fil
mov bx, di
call BufClo ;close file
mov bx, di
call BufRel ;release buffer
mov t_fil, 0FFFFH ;reset flag
pop di
texren1 ret
ENDP
;========================================
; Read a text byte.
;
; Out: AL= byte; CY= set if stop reading.
Text_Read PROC NEAR
texrea1 mov bx, t_fil ;load file block
call GetByt ;read a byte
jc texrea3
cmp al, CR ;skip carriage returns
je texrea1
cmp al, LF ;check if linefeed
jne texrea2
mov al, CR ;substitute carriage return
texrea2 clc
texrea3 ret
ENDP
;========================================
; Begin writing text.
;
; In: AX= name of file (or 0 if none).
;
; CY= set if error.
Text_Write_Beg PROC NEAR
push di
StkAll di, 80 ;allocate space for file name
cmp t_han, 0FFFFH ;check if already writing
je texwbg1
push ax
call Text_Write_End ;finish writing first
pop ax
;--- input file name
texwbg1 or ax, ax
jz texwbg2
mov bx, di
call StrCpy ;copy to buffer
jmps texwbg3
texwbg2 mov ax,OFFSET t_wri ;prompt
mov bx, di ;storage for file name
call Command_Input ;input a file name
jc texwbg8 ;jump if cancel
;--- allocate line buffer
texwbg3 mov ax, INPBUF ;buffer size
call MemAll ;allocate memory
jc texwbg7 ;jump if error
mov WORD t_lin+2,ax ;save segment
;--- open (existing) file
mov ax, di
mov cl, OPEN_WRITE ;open for writing
call FilOpn ;open file
jc texwbg5
push ax
mov bx, ax
mov cl, SEEK_END ;move to end
sub ax, ax
mov dx, ax ;offset zero from end
call FilSee ;move to end
pop ax
texwbg4 mov t_han, ax ;save handle
mov WORD t_lin, 0 ;zero offset
mov t_cur, 0 ;zero bytes in buffer
StkRel 80 ;fix stack
pop di
clc
ret
;--- couldn't open file, try creating
texwbg5 cmp al, 2 ;make sure file not found
jne texwbg6
mov ax, di
mov cl, ATTR_NORMAL ;normal attribute
call FilCre ;create file
jnc texwbg4 ;loop back if okay
;--- error or abort
texwbg6 mov ax,WORD t_lin+2 ;line buffer
call MemRel ;release memory
texwbg7 mov ax,OFFSET t_err ;error message
call Command_Error ;display
texwbg8 StkRel 80 ;fix stack
pop di
stc
ret
ENDP
;========================================
; Finish writing text.
Text_Write_End PROC NEAR
cmp t_han, 0FFFFH ;check if not open
je texend2
;--- write any extra in buffer
cmp t_cur, 0 ;check if zero bytes
je texend1
mov al, LF ;end of line
call Text_Write ;write to force end of line
;--- close file
texend1 mov bx, t_han ;handle
call FilClo ;close file
;--- release line memory
mov ax,WORD t_lin+2 ;line buffer segment
call MemRel ;release memory
mov t_han, 0FFFFH ;reset flag
texend2 ret
ENDP
;========================================
; Write a text byte.
;
; In: AL= byte.
;
; Out: CY= set if stop writing.
Text_Write PROC NEAR
cmp al, LF ;check if linefeed (end of line)
je texwrt5
cmp al, BS ;check if backspace
je texwrt3
cmp al, TAB ;check if tab
je texwrt1
cmp al, 32 ;check if control character
jb texwrt2
;--- write a character
texwrt1 push ds
lds bx, t_lin ;load current line buffer address
mov [bx], al ;store byte
pop ds
inc WORD t_lin ;increment pointer
mov ax, t_cur ;load byte count
inc ax ;increment
cmp ax, MAXLINE ;compare to maximum
je texwrt6 ;jump if buffer full
mov t_cur, ax ;save byte count
texwrt2 clc
ret
;--- backspace
texwrt3 cmp t_cur, 0 ;check if any characters in buffer
je texwrt4
dec t_cur ;decrement byte count
dec WORD t_lin ;decrement pointer
texwrt4 clc
ret
;--- end of line
texwrt5 push ds
lds bx, t_lin ;load current line buffer address
mov WORD [bx],0A0DH ;write CR+LF
pop ds
mov ax, t_cur
inc ax
inc ax
;--- write out line
texwrt6 mov bx, t_han ;handle
mov cx, ax ;bytes
mov dx,WORD t_lin+2 ;segment
sub ax, ax ;offset
call FilWri ;write line
mov WORD t_lin, 0 ;reset pointer
mov t_cur, 0 ;reset byte count
ret
ENDP
;========================================
; Xmodem user status routine.
XmdUsr PROC NEAR
push si
StkAll si, 80 ;space for prompt
push si
push ax
push bx
push dx
push cx
push ax
;=== display status
mov ax, x_prom
mov bx, si
call StrCpy
add si, ax
;--- CRC
pop dx
mov ax, OFFSET x_crc
test dl, XMODEM_CRC
jnz xmdusr1
mov ax, OFFSET x_sum
xmdusr1 mov bx, si
call StrCpy
add si, ax
;--- byte count
mov ax, OFFSET x_bytes
mov bx, si
call StrCpy
add si, ax
pop ax ;low word of byte count
pop dx ;high word of byte count
mov cx, 10 ;base
mov bx, si ;place to write number
call Num2Str ;convert to string
add si, ax ;update
;--- error count
mov ax, OFFSET x_error
mov bx, si
call StrCpy
add si, ax ;update
sub dx, dx
pop ax
push ax
mov cx, 10 ;base
mov bx, si ;place to write number
call Num2Str ;convert to string
add si, ax
;--- last error
mov ax, OFFSET x_last
mov bx, si
call StrCpy
add si, ax ;update
pop cx ;number of errors
pop ax
sub al, al
jcxz xmdusr2
mov al, ah
and al, 3FH
xmdusr2 sub ah, ah
sub dx, dx
mov cx, 10 ;base
mov bx, si ;place to write number
call Num2Str ;convert to string
;--- display
pop ax
call Command_Status ;display status line
;=== check for abort
sub si, si ;zero abort flag
jmps xmdusr4 ;enter loop
xmdusr3 cmp ax, KEY_ALT_A ;check if abort
jne xmdusr4 ;skip if not
inc si ;increment flag
xmdusr4 call KeyGet ;get keystroke
jnc xmdusr3 ;loop if key returned
;--- return
StkRel 80
sub si, 1 ;set carry if zero
cmc ;set carry if non-zero (abort)
pop si
ret
ENDP
;========================================
; Perform an xmodem download.
;
; In: AX= name of file or 0 if none; CL=
; xmodem flags; BX= serial record.
Xmodem_Download PROC NEAR
push di
push si
StkAll si, 80 ;allocate space for file name
mov di, bx ;save serial record
push ax
push cx
call Command_Open ;open command line
pop cx
pop ax
;--- input file name
or ax, ax ;check if name passed
jz xmoddn1 ;jump if not
push cx
mov bx, si
call StrCpy ;copy to buffer
pop cx
jmps xmoddn2
xmoddn1 push cx
mov ax,OFFSET x_dwn ;prompt
mov bx, si ;storage for file name
call Command_Input ;input a file name
pop cx
jc xmoddn6 ;jump if cancel
;--- check if overwrite
xmoddn2 push cx
mov ax, si
call Find_File ;check if already exists
cmc ;clear carry if not found
jnc xmoddn3 ;jump if not
mov ax, OFFSET x_conf
call Command_Confirm ;confirm command
xmoddn3 pop cx
jc xmoddn1 ;loop back to input again
;--- perform download
mov x_prom, OFFSET x_dwnp ;prompt
mov ax, si
mov bx, di
call XmdDwn ;perform download
jc xmoddn4 ;jump if error
call Beep_Success ;success beep
jmps xmoddn6
xmoddn4 cmp al, XMODEM_ABORT ;check if download aborted
je xmoddn6 ;exit if so
mov dx, OFFSET x_err ;error message
cmp al, XMODEM_FILE ;check xmodem error type
jne xmoddn5
mov dx, OFFSET t_err2 ;file error message
xmoddn5 mov ax, dx
call Command_Error ;display
xmoddn6 call Command_Close ;close command line
StkRel 80 ;fix stack
pop si
pop di
ret
ENDP
;========================================
; Perform an xmodem upload.
;
; In: AX= name of file or 0 if none; CL=
; xmodem flags; BX= serial record.
Xmodem_Upload PROC NEAR
push di
push si
StkAll si, 80 ;allocate space for file name
mov di, bx ;save serial record
push ax
push cx
call Command_Open ;open command line
pop cx
pop ax
;--- input file name
or ax, ax ;check if name passed
jz xmodup1 ;jump if not
push cx
mov bx, si
call StrCpy ;copy to buffer
pop cx
jmps xmodup2
xmodup1 push cx
mov ax,OFFSET x_upl ;prompt
mov bx, si ;storage for file name
call Command_Input ;input a file name
pop cx
jc xmodup5 ;jump if cancel
;--- perform download
xmodup2 mov x_prom, OFFSET x_uplp ;save prompt
mov ax, si
mov bx, di
call XmdUpl ;perform upload
jc xmodup3 ;jump if error
call Beep_Success ;success beep
jmps xmodup5
xmodup3 cmp al, XMODEM_ABORT ;check if upload aborted
je xmodup5 ;exit if so
mov dx, OFFSET x_err ;xmodem error message
cmp al, XMODEM_FILE ;check xmodem error type
jne xmodup4
mov dx, OFFSET t_err1 ;file error message
xmodup4 mov ax, dx
call Command_Error ;display
xmodup5 call Command_Close ;close command line
StkRel 80 ;fix stack
pop si
pop di
ret
ENDP
;========================================
; Determine if file exists by opening
; and closing.
;
; In: AX= name of file.
;
; Out: CY= set if not found.
Find_File PROC NEAR
;--- open/close file
mov cl, OPEN_READ ;access mode
call FilOpn ;try opening
jc finfil2 ;jump if error
mov bx, ax
call FilClo ;close file
finfil1 clc ;file found
ret
;--- check error code
finfil2 cmp al, 5 ;check if access denied (file exists)
je finfil1
stc
ret
ENDP